use reqwest::Client;
use reqwest::header::{HeaderMap, HeaderValue};
use serde_json::Value;
use std::collections::HashMap;
use log::{info, error};

/// 工具类 `RequestUtil` 用于发送 HTTP 请求和处理响应
pub struct RequestUtil;

impl RequestUtil {
    /// 发送带有可选参数和自定义头的 GET 请求，并返回响应的文本内容
    ///
    /// # 参数
    /// * `url` - 请求的 URL
    /// * `params` - 可选的查询参数
    /// * `headers` - 可选的自定义请求头
    ///
    /// # 返回值
    /// 返回包含响应文本的 `Result<String, Box<dyn std::error::Error>>`
    ///
    /// # 示例
    ///
    /// ```
    /// let url = "https://jsonplaceholder.typicode.com/posts/1";
    /// let params = Some([("param1", "value1")].iter().cloned().collect());
    /// let mut headers = HeaderMap::new();
    /// headers.insert("Custom-Header", HeaderValue::from_str("value").unwrap());
    /// match RequestUtil::get(url, params, Some(headers)).await {
    ///     Ok(body) => log::info!("GET response body: {}", body),
    ///     Err(e) => log::info!("GET request failed: {}", e),
    /// }
    /// ```
    pub async fn get(
        url: &str,
        params: Option<HashMap<&str, &str>>,
        headers: Option<HeaderMap>,
    ) -> Result<String, Box<dyn std::error::Error>> {
        let client = Client::new();
        let mut request = client.get(url);

        if let Some(p) = params {
            request = request.query(&p);
        }

        if let Some(h) = headers {
            request = request.headers(h);
        }

        let response = request.send().await?;
        // 检查响应状态
        if response.status().is_success() {
            // 读取响应体文本
            let body = response.text().await?;
            info!("Response Body: {}", body);
            Ok(body)
        } else {
            let status = response.status();
            error!("Request failed with status: {}", status);
            Err(format!("Request failed with status: {}", status).into())
        }
    }

    /// 发送带有可选 JSON 请求体和自定义头的 POST 请求，并返回响应的文本内容
    ///
    /// # 参数
    /// * `url` - 请求的 URL
    /// * `json` - 可选的 JSON 请求体
    /// * `headers` - 可选的自定义请求头
    ///
    /// # 返回值
    /// 返回包含响应文本的 `Result<String, Box<dyn std::error::Error>>`
    ///
    /// # 示例
    ///
    /// ```
    /// let url = "https://jsonplaceholder.typicode.com/posts";
    /// let json = Some(serde_json::json!({
    ///     "title": "foo",
    ///     "body": "bar",
    ///     "userId": 1
    /// }));
    /// let mut headers = HeaderMap::new();
    /// headers.insert("Custom-Header", HeaderValue::from_str("value").unwrap());
    /// match RequestUtil::post(url, json, Some(headers)).await {
    ///     Ok(body) => log::info!("POST response body: {}", body),
    ///     Err(e) => log::info!("POST request failed: {}", e),
    /// }
    /// ```
    pub async fn post(
        url: &str,
        json: Option<&Value>,
        headers: Option<HeaderMap>,
    ) -> Result<String, Box<dyn std::error::Error>> {
        let client = Client::new();
        let mut request = client.post(url);

        if let Some(j) = json {
            request = request.json(j);
        }

        if let Some(h) = headers {
            request = request.headers(h);
        }

        let response = request.send().await?;
        // 检查响应状态
        if response.status().is_success() {
            // 读取响应体文本
            let body = response.text().await?;
            info!("Response Body: {}", body);
            Ok(body)
        } else {
            let status = response.status();
            error!("Request failed with status: {}", status);
            Err(format!("Request failed with status: {}", status).into())
        }
    }
}
